﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WooCoo.DataPortal;
using WooCoo.IoC;
using WooCoo.ObjectModel;
using WooCoo.Reflection;
using WooCoo.Tools;

namespace WooCoo.DataPortal.Server
{
    /// <summary>
    /// 基本的业务门户处理类    
    /// </summary>
    public class SimplePortal : IDataPortalServer
    {
        #region Data Access

        /// <summary>
        /// 创建业务对象实例
        /// </summary>
        /// <param name="objectType">业务对象类型.</param>
        /// <param name="criteria">过滤条件.</param>
        /// <param name="context">
        /// <see cref="Server.DataPortalContext" /> 传递的上下文信息.
        /// </param>
        public DataPortalResult Create(object entityOrList, DataPortalContext context)
        {
            // create an instance of the business object.
            //var obj = Activator.CreateInstance(objectType, true);
            if(entityOrList is Entity)
            {
                MethodCaller.CallMethodIfImplemented(entityOrList, "DataPortal_Create");
            }else if(entityOrList is IEntityList)
            {
                MethodCaller.CallMethodIfImplemented(entityOrList, "DataPortal_Create");
            }
            else if (entityOrList is IList && ((IList)entityOrList)[0] is Entity)
            {
                (((IList)entityOrList)[0] as Entity).GetRepository().SaveChanges(entityOrList);
            }
            else
            {
                //下一步可用通过的Repository进行数据操作
                throw Error.NotSupported("不支持的实体类型");
            }
            //var svrB = ServiceBoundFactory.Instance.GetServiceType(obj.GetType());
            //if (svrB != null)
            //{
            //    svrB.BeforeInvoke(obj, new DataPortalEventArgs(context, obj.GetType(), DataPortalOperations.Create));
            //}
            //MethodCaller.CallMethodIfImplemented(obj, "DataPortal_Create", criteria);
            //if (svrB != null)
            //{
            //    svrB.InvokeComplete(obj, new DataPortalEventArgs(context, obj.GetType(), DataPortalOperations.Create));
            //}
            // return the populated business object as a result
            return new DataPortalResult(entityOrList);
        }

        /// <summary>
        /// 取得业务对象实例
        /// </summary>
        /// <param name="objectType">业务对象类型.</param>
        /// <param name="criteria">过滤条件.</param>
        /// <param name="context">
        /// <see cref="Server.DataPortalContext" /> 传递的上下文信息.
        /// </param>
        public DataPortalResult Fetch(Type objectType, object criteria, DataPortalContext context)
        {
            // create an instance of the business object.
            var obj = Activator.CreateInstance(objectType, true);
            //var entityRepository = RepositoryFactory.Instance.Find(objectType);            
            //var svrB = ServiceBoundFactory.Instance.GetServiceType(obj.GetType());
            //if (svrB != null)
            //{
            //    svrB.BeforeInvoke(obj, new DataPortalEventArgs(context, obj.GetType(), DataPortalOperations.Fetch));
            //}
            MethodCaller.CallMethodIfImplemented(obj, "DataPortal_Fetch", criteria);
            //if (svrB != null)
            //{
            //    svrB.InvokeComplete(obj, new DataPortalEventArgs(context, obj.GetType(), DataPortalOperations.Fetch));
            //}

            //var entityobj = obj as Entity;
            //if (entityobj != null)
            //{
            //    //当没有获取数据时，返回NULL;
            //    if (entityobj.IsNew)
            //        return new DataPortalResult(null);
            //}
            // return the populated business object as a result
            return new DataPortalResult(obj);
        }

        /// <summary>
        /// 更新业务对象.
        /// </summary>
        /// <param name="obj">需要更新的业务对象.</param>
        /// <param name="context">
        /// <see cref="Server.DataPortalContext" /> 传递的上下文信息.
        /// </param>
        public DataPortalResult Update(object entityOrList, DataPortalContext context)
        {
            Check.CheckArgumentNull(entityOrList, "entityOrList");
            if (entityOrList is Entity)
            {
                MethodCaller.CallMethodIfImplemented(entityOrList, "DataPortal_Update");
            }
            else if (entityOrList is IEntityList)
            {
                //EntityList
                MethodCaller.CallMethodIfImplemented(entityOrList, "DataPortal_Update");
                //((obj as IList)[0] as Entity).GetRepository().Update(obj);
            }
            else if (entityOrList is IList && ((IList)entityOrList)[0] is Entity)
            {
                (((IList)entityOrList)[0] as Entity).GetRepository().SaveChanges(entityOrList);
            }
            else
                throw Error.NotSupported("不支持的实体类型");
            //var svrB = ServiceBoundFactory.Instance.GetServiceType(obj.GetType());
            //if (svrB != null)
            //{
            //    svrB.BeforeInvoke(obj, new DataPortalEventArgs(context, obj.GetType(), DataPortalOperations.Update));
            //}
            //MethodCaller.CallMethodIfImplemented(obj, "DataPortal_Update");
            //if (svrB != null)
            //{
            //    svrB.InvokeComplete(obj, new DataPortalEventArgs(context, obj.GetType(), DataPortalOperations.Update));
            //}
            return new DataPortalResult(entityOrList);
        }

        /// <summary>
        /// 直接从数据库中删除请求.
        /// </summary>
        /// <param name="objectType">业务对象类型.</param>
        /// <param name="criteria">查询条件.</param>
        /// <param name="context">
        /// <see cref="Server.DataPortalContext" /> 传递的上下文.
        /// </param>
        public DataPortalResult Delete(Type objectType, object criteria, DataPortalContext context)
        {
            var obj = Activator.CreateInstance(objectType, true);
            //var svrB = ServiceBoundFactory.Instance.GetServiceType(obj.GetType());
            //if (svrB != null)
            //{
            //    svrB.BeforeInvoke(obj, new DataPortalEventArgs(context, obj.GetType(), DataPortalOperations.Delete));
            //}
            MethodCaller.CallMethodIfImplemented(obj, "DataPortal_Delete", criteria);
            //if (svrB != null)
            //{
            //    svrB.InvokeComplete(obj, new DataPortalEventArgs(context, obj.GetType(), DataPortalOperations.Delete));
            //}
            return new DataPortalResult(obj);
        }
        /// <summary>
        /// 请求命令
        /// </summary>
        /// <param name="requestMethod"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public DataPortalResult Execute(object target,ActionInfo requestMethod, DataPortalContext context)
        {
            //object obj;
            //Container.Current.TryGetExports(requestMethod.ContractName, out obj);
            var result = MethodCaller.CallMethod(target, requestMethod.MethodName, requestMethod.Parameters);
            return new DataPortalResult(result);
        }
        #endregion
    }
}
